package com.mxx.common.netty.http;

import com.mxx.common.netty.exception.IllegalMethodNotAllowedException;
import com.mxx.common.netty.exception.IllegalPathNotFoundException;
import com.mxx.common.netty.http.validate.ParameterValidator;
import com.mxx.common.netty.interceptor.Finish;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.HttpMethod;
import io.netty.handler.codec.http.HttpResponseStatus;
import lombok.extern.slf4j.Slf4j;

import java.util.Collection;
import java.util.concurrent.Executors;

/**
 * @Auther: Mr. Zeng
 * @Date: 2020/7/17 17:22
 * @Description: 默认的Http处理器操作类
 */
@Slf4j

public class DefaultNettyHttpOperator extends AbstractNettyHttpOperator {

    public DefaultNettyHttpOperator(String contextPath) {
        super(contextPath, Executors.newCachedThreadPool(runnable -> {
            Thread thread = Executors.defaultThreadFactory().newThread(runnable);
            thread.setName("NettyHttpHandler-" + thread.getName());
            return thread;
        }));

    }

    @Override
    public NettyHttpResponse onReceivedRequest(ChannelHandlerContext context, NettyHttpRequest request) {
        NettyMethod httpMethod = null;
        NettyHttpResponse response = null;
        try {
            if (request.getMethod().equals(HttpMethod.OPTIONS)) {
                response = super.getResponseFactory().newEmpty();
            } else {
                httpMethod = super.matchMethod(request);
            }

        } catch (IllegalMethodNotAllowedException error) {
            log.info("request url {} : {} ,method not allowed ", request.getMethod().name(), request.getUri());
            response = super.getResponseFactory().newResponse(HttpResponseStatus.METHOD_NOT_ALLOWED);
        } catch (IllegalPathNotFoundException error) {
            log.info("request url {} : {} ,path not found ", request.getMethod().name(), request.getUri());
            response = super.getResponseFactory().newResponse(HttpResponseStatus.NOT_FOUND);
        }


        if (httpMethod != null) {

            /**
             * 前置拦截
             */
            Finish finish;
            if ((finish = super.doInterceptor(context, request, httpMethod, interceptor -> interceptor::before)).doIntercept()) {
                return finish.getResponse();
            }
            /**
             * 剧中拦截
             */
            if ((finish = super.doInterceptor(context, request, httpMethod, interceptor -> interceptor::complete)).doIntercept()) {
                return finish.getResponse();
            }
            /**
             *  具体方法执行
             */
            try {
                Object result = httpMethod.invoke(request);
                response = super.getResponseFactory().catchResponse(result);
            } catch (Throwable error) {
                response = super.getResponseFactory().catchThrowable(error);
            }
            /**
             * 后置拦截
             */
            if ((finish = super.doInterceptor(context, request, (NettyHttpResponse) response, httpMethod, interceptor -> interceptor::after)).doIntercept()) {
                return finish.getResponse();
            }

            /**
             * 输出结果
             */
        }
        return response;
    }


}
